package gitobject;

import java.io.*;
import java.util.ArrayList;

import fileoperation.FileReader;
import sha1.SHA1;
import repository.Repository;
import zlib.ZLibUtils;


public class Commit extends GitObject{
    protected String tree; 		// the sha1 value of present committed tree
    protected String parent; 	// the sha1 value of the parent commit
    protected String author; 	// the author's name and timestamp
    protected String committer; // the committer    's info
    protected String message; 	// the commit memo

    public String getParent(){return parent;}
    public String getTree(){return tree;}
    public String getAuthor(){return author;}
    public String getCommitter(){return committer;}
    public String getMessage(){return message;}

    //空构造函数
    public Commit(){}

    /**
     * Construct a commit from a built tree.
     * @param
     * author, committer, message参数在git commit命令里创建
     * @throws Exception
     */

    public Commit(Tree tree, String author, String committer) throws Exception {
        this.fmt = "commit";        // 类型为commit
        this.tree = tree.getKey();
        this.parent = getLastCommit() == null ? "" : getLastCommit();
        this.author = author;
        this.committer = committer;
        this.value = "tree " + this.tree + "\nparent " + this.parent+ "\nauthor " + this.author + "\ncommitter "
                + this.committer + "\n";
        this.key = genKey();
        // 每次Commit，都要创建一个HEAD，Branch
        File HEAD = new File(Repository.getGitDir() + File.separator + "HEAD");
        File branchFile = new File(Repository.getGitDir() + File.separator + path);
    }
    
    /**
     * Deserialize the commit object from its key(commitId)
     * @param commitId
     * @throws IOException
     */

    // 构造deserialize方法，作用是根据哈希值，把commit对象写入io流中
    public void deserialize(String commitId) throws IOException {
        // key 为commit对象哈希值的五位子串
        String key = commitId.substring(5);
        // 构造存放的路径
        String parentPath = Repository.getGitDir() + File.separator + "objects";
        String path = parentPath + File.separator + key;
        // 新建数据文件
        File file = new File(path);
        // 如果不是文件夹，先建立数据通道，再解压缩，最后关闭流
        if(file.isFile()){
            FileInputStream is = new FileInputStream(file);
            byte[] content = ZLibUtils.decompress(is);
            is.close();
            // value值就是解压缩后的数据
            value = new String(content);
            // 以下方法从FileReader中引用而来，实现从一个commit对象的value值中得到tree对象
            tree = FileReader.readCommitTree(value);
            parent = FileReader.readCommitParent(value);
            author = FileReader.readCommitAuthor(value);
            committer = FileReader.readCommitter(value);
            message = FileReader.readCommitMsg(value);
        }
    }

    /**
     * Generate the hash value of this commit.
     * @return key
     * */
    public String genKey() throws Exception {
        key = SHA1.getHash(value);
        return key;
    }

    /**
     * Get the parent commit from the HEAD file.
     * @return
     * @throws IOException
     */
    public static String getLastCommit() throws IOException {
        File HEAD = new File(Repository.getGitDir() + File.separator + "HEAD");

        String path = getValue(HEAD).substring(5).replace("\n", "");
        File branchFile = new File(Repository.getGitDir() + File.separator + path);

        if (branchFile.isFile()) {
            return getValue(branchFile);
        } else {
            return null;
        }
    }
}

